﻿using Dispatch.Receive;
using Dispatch.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace Dispatch.DispatchData
{
    /// <summary>
    /// agv的实时数据，可写缓存也不可写缓存
    /// agv在启动后将不停的收到数据，缓存中的不是实时的，没多大的意义
    /// </summary>
    public class AgvData
    {
        public int AgvID { get; set; }
        public string IP { get; set; } ="";
        public int Port { get; set; }

        public int X { get; set; }
        public int Y { get; set; }

        public int LastX { get; set; }
        public int LastY { get; set; }

        //朝向弧度 
        public float Radian { get; set; }
         
    }
     

    public class AgvDataSet
    {
        static  List<AgvData> agvList=new List<AgvData>(); //所有有效的AGV
     

        #region 初始化数据
        /// <summary>
        /// 初始化数据
        /// </summary>
        /// <param name="list"></param>
        public static void FillData(List<AgvData> list)
        {
            lock (agvList)
            {
                agvList.Clear();
                agvList.AddRange(list);
            }
        }

       
        #endregion

        /// <summary>
        /// 更新AGV的状态
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        internal static Task UpdateAgvAsync(AgvReceiveData data)
        {
            lock (agvList)
            {
                AgvData? agvData=agvList.Find(x => x.AgvID == data.AgvID);
                if (agvData != null)
                {
                    
                    agvData.LastX = agvData.X;
                    agvData.LastY = agvData.Y;
                    agvData.X = data.X;
                    agvData.Y = data.Y;
                    if(agvData.X!=agvData.LastX || agvData.Y != agvData.LastY)
                    {
                        //有数据发生了变化
                        agvData.Radian = MathF.Abs(MathF.Atan2(agvData.Y - agvData.LastY, agvData.X - agvData.LastX)); 
                        //180度的修正
                        if(agvData.X>=agvData.LastX && agvData.Y >= agvData.LastY)
                        {
                            //右上方
                        }else if(agvData.X <= agvData.LastX && agvData.Y <= agvData.LastY)
                        {
                            //左下方
                            agvData.Radian += Config.Angle90 * 2;
                        }
                        else if (agvData.X <= agvData.LastX && agvData.Y >= agvData.LastY)
                        {
                            //左上方
                            agvData.Radian += Config.Angle90;
                        }
                        else if (agvData.X >= agvData.LastX && agvData.Y <= agvData.LastY)
                        {
                            //右下方
                            agvData.Radian+= Config.Angle90 * 3;
                        }
                    } 
                }

            }
            return Task.CompletedTask;
        }

        /// <summary>
        /// 获取指定的AGV
        /// </summary>
        /// <param name="AgvID"></param>
        /// <returns></returns>
        public static AgvData? GetAgvData (int AgvID )
        {
            AgvData? obj = null;
            lock (agvList)
            {
                AgvData? agvData = agvList.Find(x => x.AgvID ==  AgvID);
                if(agvData != null)
                {
                    obj = Tools.Copy(agvData);
                }
            }
            return obj;
        }

       

        /// <summary>
        /// 获取一个大致区域内的所有AGV及其位置（初次过滤）
        /// </summary>
        /// <param name="MinX"></param>
        /// <param name="MinY"></param>
        /// <param name="MaxX"></param>
        /// <param name="MaxY"></param>
        /// <param name="ExceptAgvID"></param>
        /// <returns></returns>
        public static Task<List<AgvData>> GetAgvListAsync(int MinX,int MinY,int MaxX,int MaxY,int ExceptAgvID)
        {
            List<AgvData> list = new List<AgvData>();    
            lock (agvList)
            {
                var tmp= agvList.Where(p=>p.AgvID!= ExceptAgvID && MinX <=p.X && p.X<=MaxX &&MinY<=p.Y &&p.Y<=MaxY).ToList();
                tmp.ForEach(p =>
                {
                    AgvData agvData = new AgvData()
                    {
                        AgvID = p.AgvID,
                        X = p.X,
                        Y = p.Y, 
                    };
                    list.Add(agvData);
                });
            }
            return Task.FromResult<List<AgvData>>(list);
        }



        /// <summary>
        /// 向AGV发送指令
        /// </summary>
        /// <param name="agvID"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static Task SendToAgvAsync(int agvID,byte[] data)
        {
            if (agvID <= 0||data.Length==0)
            {
                return Task.CompletedTask;
            }
            AgvData? agv=GetAgvData(agvID);
            if (agv == null)
            {
                return Task.CompletedTask;
            }
            _=Tools.SendDataToAgvAsync(agv.IP,agv.Port,data);
            return Task.CompletedTask;
        }


        #region 写缓存

        Task ToCache()
        {
            return Task.CompletedTask;
        }


        #endregion
    }
}
